package genedit.view.graph;

import genedit.gui.exceptions.ElementNePostoji;
import genedit.model.graph.GraphElement;
import genedit.model.graph.Property;
import genedit.model.graph.classModel.ClassModel;
import genedit.model.graph.classModel.GAttribute;
import genedit.model.graph.classModel.GAttributes;
import genedit.model.graph.classModel.GMethod;
import genedit.model.graph.classModel.GMethods;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;

public class ClassModelPainter extends MyRectPainter {
	
	protected int textHeightGlobal;

	public ClassModelPainter(GraphElement element) {
		super(element);
		transform = new AffineTransform();
		
		shape = new java.awt.geom.Rectangle2D.Double(0, 0, element.getSize()
				.getWidth(), element.getSize().getHeight());
	}
	
	@Override
	public void paint(Graphics2D g) {
		
		ClassModel element=(ClassModel)getElement();
		
		Color backupColor=g.getColor();
		g.setColor(element.getColor());
		Stroke backupStroke = g.getStroke();
		g.setStroke(element.getStroke());
		Paint backupPaint = g.getPaint();
		
		AffineTransform backupTransformation=g.getTransform();
		refreshAffine();
		g.transform(transform);
		
		Shape classShape = new Rectangle(0,0,(int) element.getSize().getWidth(),(int) element.getSize().getHeight());
		Paint fill = new GradientPaint(0, 0, Color.CYAN, (int) element.getSize().getWidth(), (int) element.getSize().getHeight(), Color.WHITE);
		g.setPaint(fill);
	    g.fill(classShape);
	    g.setPaint(backupPaint);
	    
		Shape backupClip = g.getClip();
		g.draw(shape);
		
		//iscrtaj dve linije
		Rectangle2D baseShapeRect=shape.getBounds2D();
		g.drawLine(0,(int) (baseShapeRect.getHeight()/3),(int) (baseShapeRect.getWidth()), (int) (baseShapeRect.getHeight()/3));
		g.drawLine(0,(int) (2*baseShapeRect.getHeight()/3),(int) (baseShapeRect.getWidth()), (int) (2*baseShapeRect.getHeight()/3));
		
		// iscrtavanje imena ClassModel-a
		//g.setClip(backupClip);
		Rectangle clipName = new Rectangle(0,0,(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3));
		g.setPaint(Color.BLACK);
		g.setFont(new Font("Arial",Font.BOLD,9));
		FontMetrics fm = g.getFontMetrics(g.getFont());
		Rectangle2D rectangle = fm.getStringBounds(element.getName(), g);
	    textHeightGlobal = (int)(rectangle.getHeight());
	    g.clipRect(clipName.x, clipName.y, clipName.width, clipName.height);
		drawCenteredStringConcrete(g,element.getName(),0,0,(int)element.getSize().getWidth(),(int)element.getSize().getHeight(), 0);
		
		// iscrtavanje atributa ClassModel-a
		g.setClip(backupClip);
		Rectangle clipAtributes = new Rectangle(0,(int)(element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3));
		g.setPaint(Color.BLACK);
		g.setFont(new Font("Arial",Font.BOLD,9));
		g.clipRect(clipAtributes.x, clipAtributes.y, clipAtributes.width, clipAtributes.height);
		
		Iterator<Property> it = element.getIteratorProperties();
		Property attributes = null;
		Property methods = null;
		while(it.hasNext()) {
			Property temp = it.next();
			if(temp.getKey().equals("attributes")) {
				
				attributes = temp;
				
			} else if (temp.getKey().equals("methods")) {
				
				methods = temp;
			}
		}
		
		GAttributes attribute = (GAttributes)attributes.getValue();
		GMethods method = (GMethods)methods.getValue();		
		
		
		ArrayList<GAttribute> at = new ArrayList<GAttribute>();
		ArrayList<GMethod> met = new ArrayList<GMethod>();
		
		Iterator<String> itAtt = attribute.getAtributeIterator();
		
		while(itAtt.hasNext()) {
			String att = itAtt.next();
			try {
				at.add(attribute.getAtribute(att));
			} catch (ElementNePostoji e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		at.addAll(attribute.getInheritedAttributes().values());
		
		for(int i = 0; i < at.size(); ++i) {
			drawCenteredStringConcrete(g,(at.get(i)).toString(),0,(int)(i*textHeightGlobal + element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3), i);
		}
		
		// iscrtavanje metoda ClassModel-a
		g.setClip(backupClip);
		Rectangle clipMethods = new Rectangle(0,(int)(2*element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3));
		g.setPaint(Color.BLACK);
		g.setFont(new Font("Arial",Font.BOLD,9));
		g.clipRect(clipMethods.x, clipMethods.y, clipMethods.width, clipMethods.height);

		Iterator<String> itMth = method.getMethodIterator();
		
		while(itMth.hasNext()) {
			String mth = itMth.next();
			try {
				met.add(method.getMethod(mth));
			} catch (ElementNePostoji e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		met.addAll(method.getInheritedMethods());
		
		for(int i = 0; i < met.size(); ++i) {
		    drawCenteredStringConcrete(g,(met.get(i)).toString(),0,(int)(i*textHeightGlobal + 2*element.getSize().getHeight()/3),(int)element.getSize().getWidth(),(int)(element.getSize().getHeight()/3), i);
		}
	
		g.setClip(backupClip);
		g.setTransform(backupTransformation);
		g.setStroke(backupStroke);
		g.setColor(backupColor);
		g.setPaint(backupPaint);
	}
	
	/**
	 * Metoda se koristi za iscrtavanje naziva ClassModel u prvoj treÄ‡ini elementa
	 * 
	 * @param g2d kontekst u kojem se iscrtava string
	 * @param s string koji se iscrtava
	 * @param x poÄ�etna X-koordinata MyRect
	 * @param y poÄ�etna Y-koordinata MyRect
	 * @param width Å¡irina ClassModel
	 * @param height visina ClassModel
	 * @param i offset
	 */
	public void drawCenteredStringConcrete(Graphics2D g2d, String s, int x, int y, int width, int height, int i) {
		// Nalazi veliÄ�inu stringa s odgovarajuÄ‡eg fonta u konekstu g2d
	    FontMetrics fm   = g2d.getFontMetrics(g2d.getFont());
	    Rectangle2D rect = fm.getStringBounds(s, g2d);
	    int textHeight = (int)(rect.getHeight());
	    int textWidth  = (int)(rect.getWidth());
	    // Centrira tekst horizontalno i vertikalno za granice pravougaonika koje su mu prosleÄ‘ene
	    int textX = x + (width - textWidth)/2;
	    int textY = y + (height - textHeight)/2  +  fm.getAscent() + i -  height/3;
	    g2d.drawString(s, textX, textY);
	  }
	


}
